/*
 * AttributeParser.java
 *
 * Copyright (c) 2008 Teamnet. All Rights Reserved.
 *
 * This source file may not be copied, modified or redistributed,
 * in whole or in part, in any form or for any reason, without the express
 * written consent of Teamnet.
 */

package ro.prj.manager.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.regex.Pattern;
import java.util.StringTokenizer;
import java.util.List;

/**
 * This class is used to todo
 */
public class AttributeParser {
    private static Log log = LogFactory.getLog(AttributeParser.class);
    private static final String strClass="/*\n" +
                " * Column.java\n" +
                " *\n" +
                " * Copyright (c) 2008 Teamnet. All Rights Reserved.\n" +
                " *\n" +
                " * This source file may not be copied, modified or redistributed,\n" +
                " * in whole or in part, in any form or for any reason, without the express\n" +
                " * written consent of Teamnet.\n" +
                " */\n" +
                "package ro.prjmanager.database.model;\n" +
                "\n" +
                "import ro.prjmanager.bundle.util.Utils;\n" +
                "import ro.teamnet.generator.constants.BackendConstants;\n" +
                "\n" +
                "import java.util.List;\n" +
                "import java.util.ArrayList;\n" +
                "import java.util.Arrays;\n" +
                "\n" +
                "/**\n" +
                " * This class maps an database column\n" +
                " */\n" +
                "public class Column {\n" +
                "    //hold the datbase column name\n" +
                "    private String databaseColumnName;\n" +
                "    //hold the java column name\n" +
                "    private String javaColumnName;\n" +
                "    //hold the coresponding Java type\n" +
                "    private String javaType;\n" +
                "    //hold the coresponding Database type\n" +
                "    private String databaseType;\n" +
                "    //hold the column index from the table\n" +
                "    private int idx;\n" +
                "    //true if this column is primary key\n" +
                "    private boolean primaryKey;\n" +
                "    //true if this columns is foreign key\n" +
                "    private boolean foreignKey;\n" +
                "    //this attribute hold the nullable propertye of this column\n" +
                "    private boolean nullable;\n" +
                "    //the table that hold this column\n" +
                "    private Table ownerTable;\n" +
                "    //hold the refered column\n" +
                "    private Column foreingColumn;\n" +
                "    //hold the foreing key columns that refer this primary key\n" +
                "    //if this attribute is not null than this column is an primary key\n" +
                "    private List<Column> relationColumns;\n" +
                "    //hold the column size in byte\n" +
                "    private int columnSize;\n" +
                "    \n" +
                "\n" +
                "\n" +
                "    /**\n" +
                "     * This is the default constructor\n" +
                "     */\n" +
                "    public Column() {\n" +
                "\n" +
                "    }\n" +
                "\n" +
                "\n" +
                "    public String getDatabaseColumnName() {\n" +
                "        return databaseColumnName;\n" +
                "    }\n" +
                "\n" +
                "    public void setDatabaseColumnName(String databaseColumnName) {\n" +
                "        this.databaseColumnName = databaseColumnName;\n" +
                "    }\n" +
                "\n" +
                "    public String getJavaColumnName() {\n" +
                "        return javaColumnName;\n" +
                "    }\n" +
                "\n" +
                "    public void setJavaColumnName(String javaColumnName) {\n" +
                "        this.javaColumnName = javaColumnName;\n" +
                "    }\n" +
                "\n" +
                "    public String getJavaType() {\n" +
                "        return javaType;\n" +
                "    }\n" +
                "\n" +
                "    public void setJavaType(String javaType) {\n" +
                "        this.javaType = javaType;\n" +
                "    }\n" +
                "\n" +
                "    public String getDatabaseType() {\n" +
                "        return databaseType;\n" +
                "    }\n" +
                "\n" +
                "    public void setDatabaseType(String databaseType) {\n" +
                "        this.databaseType = databaseType;\n" +
                "    }\n" +
                "\n" +
                "    public int getIdx() {\n" +
                "        return idx;\n" +
                "    }\n" +
                "\n" +
                "    public void setIdx(int idx) {\n" +
                "        this.idx = idx;\n" +
                "    }\n" +
                "\n" +
                "    public boolean isPrimaryKey() {\n" +
                "        return primaryKey;\n" +
                "    }\n" +
                "\n" +
                "    public void setPrimaryKey(boolean primaryKey) {\n" +
                "        this.primaryKey = primaryKey;\n" +
                "    }\n" +
                "\n" +
                "    public Column getForeingColumn() {\n" +
                "        return foreingColumn;\n" +
                "    }\n" +
                "\n" +
                "    public void setForeingColumn(Column foreingColumn) {\n" +
                "        this.foreingColumn = foreingColumn;\n" +
                "    }\n" +
                "\n" +
                "    public Table getOwnerTable() {\n" +
                "        return ownerTable;\n" +
                "    }\n" +
                "\n" +
                "    public void setOwnerTable(Table ownerTable) {\n" +
                "        this.ownerTable = ownerTable;\n" +
                "    }\n" +
                "\n" +
                "    public boolean isNullable() {\n" +
                "        return nullable;\n" +
                "    }\n" +
                "\n" +
                "    public void setNullable(boolean nullable) {\n" +
                "        this.nullable = nullable;\n" +
                "    }\n" +
                "\n" +
                "    public boolean isForeignKey() {\n" +
                "        return foreignKey;\n" +
                "    }\n" +
                "\n" +
                "    public void setForeignKey(boolean foreignKey) {\n" +
                "        this.foreignKey = foreignKey;\n" +
                "    }\n" +
                "\n" +
                "    public int getColumnSize() {\n" +
                "        return columnSize;\n" +
                "    }\n" +
                "\n" +
                "    public void setColumnSize(int columnSize) {\n" +
                "        this.columnSize = columnSize;\n" +
                "    }\n" +
                "\n" +
                "    public List<Column> getRelationColumns() {\n" +
                "        return relationColumns;\n" +
                "    }\n" +
                "\n" +
                "    public void setRelationColumns(List<Column> relationColumns) {\n" +
                "        this.relationColumns = relationColumns;\n" +
                "    }\n" +
                "\n" +
                "    /**\n" +
                "     * This method is an delegate over the relationColumns\n" +
                "     * and add an relation column to the list of the relations\n" +
                "     * @param relationalColumn - the relational column\n" +
                "     * @return - true if the opperation has been successfully\n" +
                "     */\n" +
                "    public boolean add(Column relationalColumn) {\n" +
                "        if(relationColumns==null)\n" +
                "            relationColumns=new ArrayList<Column>();\n" +
                "        return relationColumns.add(relationalColumn);\n" +
                "    }\n" +
                "\n" +
                "    /**\n" +
                "     * This method merge the properties of an givven Column object over the\n" +
                "     * properties of the current object\n" +
                "     * @param col - The givven Column object\n" +
                "     */\n" +
                "    public void merge(Column col) {\n" +
                "\n" +
                "        if (databaseColumnName == null)\n" +
                "            databaseColumnName = col.databaseColumnName;\n" +
                "        if (javaColumnName == null)\n" +
                "            javaColumnName = col.javaColumnName;\n" +
                "        if (javaType == null)\n" +
                "            javaType = col.javaType;\n" +
                "        if (databaseType == null)\n" +
                "            databaseType = col.databaseType;\n" +
                "        if (idx == 0)\n" +
                "            idx = col.idx;\n" +
                "        if (!primaryKey)\n" +
                "            primaryKey = col.primaryKey;\n" +
                "        if (!foreignKey)\n" +
                "            foreignKey = col.foreignKey;\n" +
                "        if (!nullable)\n" +
                "            nullable = col.nullable;\n" +
                "        if (ownerTable == null)\n" +
                "            ownerTable = col.ownerTable;\n" +
                "        if (foreingColumn == null)\n" +
                "            foreingColumn = col.foreingColumn;\n" +
                "        if (columnSize == 0)\n" +
                "            columnSize = col.columnSize;\n" +
                "        if(relationColumns==null)\n" +
                "            relationColumns=col.relationColumns;\n" +
                "    }\n" +
                "\n" +
                "    /**\n" +
                "     * This method build the coresponding getter name for this column\n" +
                "     * @return - the getter name for the column\n" +
                "     */\n" +
                "    public String getter(){\n" +
                "        return BackendConstants.GET + getJavaColumnName().substring(0,1).toUpperCase()+getJavaColumnName().substring(1);\n" +
                "    }\n" +
                "\n" +
                "    /**\n" +
                "     * This method build the coresponding setter name for this column\n" +
                "     * @return - the setter name for the column\n" +
                "     */\n" +
                "    public String setter(){\n" +
                "       return BackendConstants.SET + getJavaColumnName().substring(0,1).toUpperCase()+getJavaColumnName().substring(1);\n" +
                "    }\n" +
                "\n" +
                "    /**\n" +
                "     * This method return true if other columns are foreign key to this column\n" +
                "     * @return true if other columns are foreign key to this column\n" +
                "     */\n" +
                "    public boolean hasOtherRelations(){\n" +
                "        return relationColumns!=null&&!relationColumns.isEmpty();\n" +
                "    }\n" +
                "\n" +
                "\n" +
                "    public String toString() {\n" +
                "        return \"Column{\" +\n" +
                "                \"databaseColumnName='\" + databaseColumnName + '\\'' +\n" +
                "                \", javaColumnName='\" + javaColumnName + '\\'' +\n" +
                "                \", javaType='\" + javaType + '\\'' +\n" +
                "                \", databaseType='\" + databaseType + '\\'' +\n" +
                "                \", idx=\" + idx +\n" +
                "                \", primaryKey=\" + primaryKey +\n" +
                "                \", foreignKey=\" + foreignKey +\n" +
                "                \", nullable=\" + nullable +\n" +
                "                \", foreingColumn=\" + foreingColumn +\n" +
                "                \", columnSize=\" + columnSize +(relationColumns==null||relationColumns.isEmpty()?\"\":\n" +
                "                \", relationColumns=\"+ Arrays.toString(relationColumns.toArray()) )+\n" +
                "                '}';\n" +
                "    }\n" +
                "\n" +
                "    public static void main(String[] args) {\n" +
                "        String p;\n"+
                "        Column col=new Column();\n" +
                "        col.setDatabaseColumnName(\"ID_USERS\");\n" +
                "        System.out.println(col.getter());\n" +
                "\n" +
                "    }\n" +
                "}";

    public static final String TYPE_REG_EX="[ ]*(int|boolean|short|byte|float|long|void|[A-Z][A-z]*|[A-Z][A-z]*<[A-Z][A-z]*>|[A-Z][A-z]*<[A-Z][A-z]*<[\\w]*>>) [ ]*";
    public static final String MODIFICATORI_REG_EX="[ ]*(private|public|protected|) [ ]*";
    public static final String KEYWORD_REG_EX="[ ]*(static|)[ ]*(final|)[ ]*(synchronized|)[ ]*";

    public static final String ATTRIBUTE_REG_EX=MODIFICATORI_REG_EX+KEYWORD_REG_EX+TYPE_REG_EX+"[a-z][\\w]*[ ]*;[ ]*";
    public static final String METHOD_REG_EX=MODIFICATORI_REG_EX+KEYWORD_REG_EX+TYPE_REG_EX+"[\\w]*[ ]*";



    protected static List<String> substractMethod(){
        String classBody=strClass.substring(strClass.indexOf("{")+1,strClass.lastIndexOf("}")) ;
        StringTokenizer st=new StringTokenizer(classBody,"(){}");
        while(st.hasMoreTokens()){
            System.out.println("Statement:"+st.nextToken());
        }

       return null;
    }


    public static void main(String[] args) {
//         substractMethod();
        

         Pattern pattern =
                    Pattern.compile(METHOD_REG_EX );
//        String str="protected String s1_;";
        StringTokenizer st=new StringTokenizer(strClass,"\n");
        while(st.hasMoreTokens()){
//            System.out.println(st.nextToken());
            String str=st.nextToken();

//            System.out.println(pattern.matcher(str).lookingAt());
            if(pattern.matcher(str).lookingAt()&&str.indexOf("(")>0){
                System.out.println(str);
            }

        }


        try{
//        System.out.println(pattern.matcher(str).matches());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
